import { withI18n, useI18n, GetI18nServerSideProps, getRequestLanguage, supportLanguages } from "../i18n";
import React, { useEffect, FunctionComponent } from "react";
import { useCookie } from "react-use";
import { useLocalStore, useObserver } from "mobx-react-lite";
import "mobx-react-lite/batchingForReactDom";
import classNames from "classnames";
import querystring from "query-string";
import { pki } from "node-forge";
import { Request, Response } from "express";
import axios from "axios";
import openapi, { Auth1SendauthvcodeReqDeviceinfo } from "@anyshare/openapi";
import {
    eacpPublicApi,
    eacpPrivateApi,
    authenticationPrivateApi,
    getServiceNameFromApi,
    getErrorCodeFromService,
} from "../core/config";
import { getLoginRequest, acceptLoginRequest } from "../services/hydra";
import { ErrorCode, getErrorMessage } from "../core/errorcode";
import Button from "antd/lib/button";
import Input from "antd/lib/input";
import Form from "antd/lib/form";
import { Password } from "../controls";
import Checkbox from "antd/lib/checkbox";
import { AuthBySMS, AppHead } from "../components";
import { AvatarColored, AccountColored, PasswordColored, DynamicPasswordColored } from "@anyshare/icons";
import ErrorPage from "./_error";

interface ISigninProps {
    /**
     * 认证唯一标识
     */
    challenge?: string;

    /**
     * csrf token令牌
     */
    csrftoken: string;

    /**
     * 登录设备信息
     */
    device?: Auth1SendauthvcodeReqDeviceinfo;

    /**
     * 认证配置
     */
    authconfig?: { [key: string]: any };

    /**
     * oem配置
     */
    oemconfig?: { [key: string]: any };

    /**
     * 错误信息
     */
    error?: { [key: string]: any } | null;

    /**
     * 是否是IE浏览器
     */
    isIE?: boolean;

    userAgent?: string | undefined;
}

interface ISigninState {
    /**
     * 选择语言
     */
    languageUser: string;

    /**
     * 登录状态
     */
    loginStatus: LoginStatus;

    /**
     * 账号
     */
    account: string;

    /**
     * 密码
     */
    password: string;

    /**
     * 图形验证码信息
     */
    captchaInfo: CaptchaInfo;

    /**
     * 图形验证码
     */
    captcha: string;

    /**
     * 动态密码
     */
    dynamicPassword: string;

    /**
     * 是否记住登录状态
     */
    rememberLogin: boolean;

    /**
     * 认证方式
     */
    authMethod: AuthMethod;

    /**
     * 是否需要短信验证码
     */
    needAuthBySMS: boolean;

    /**
     * 短信验证码绑定手机号
     */
    cellphone: string;

    /**
     * 发送短信验证码时间间隔
     */
    timeInterval: number;

    /**
     * 是否重复发送短信验证码
     */
    isDuplicateSend: boolean;

    /**
     * 错误状态码
     */
    errorStatus: number;

    /**
     * 错误信息
     */
    errorInfo: any;

    /**
     * 校验输入
     */
    checkInput: () => boolean;

    /**
     * 获取图形验证码信息
     */
    getCaptchaInfo: () => void;

    /**
     * 认证
     */
    auth: () => void;

    [key: string]: any;
}

/**
 * 登录操作
 */
export enum LoginStatus {
    /**
     * 登录
     */
    READY,

    /**
     * 登录中
     */
    LOADING,
}

/**
 * 登录方式
 */
export enum AuthMethod {
    /**
     * 账号密码
     */
    Account,

    /**
     * 图形密码
     */
    AccountAndImgCaptcha,

    /**
     * 短信验证码
     */
    AccountAndSmsCaptcha,

    /**
     * 动态密码
     */
    AccountAndDynamicPassword,
}

/**
 * 验证码信息
 */
export interface CaptchaInfo {
    /**
     * 验证码标识
     */
    uuid: string;

    /**
     * 验证码图片
     */
    vcode: string;
}

const PublicKey: any = pki.publicKeyFromPem(`-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7JL0DcaMUHumSdhxXTxqiABBC
DERhRJIsAPB++zx1INgSEKPGbexDt1ojcNAc0fI+G/yTuQcgH1EW8posgUni0mcT
E6CnjkVbv8ILgCuhy+4eu+2lApDwQPD9Tr6J8k21Ruu2sWV5Z1VRuQFqGm/c5vaT
OQE5VFOIXPVTaa25mQIDAQAB
-----END PUBLIC KEY-----`);

const OAuthIsSkipLabel = "oauth2.isSkip";
const isSkipMaxAge = 60 * 60 * 1000 * 24 * 30;

export const SignInForm: FunctionComponent<Omit<ISigninProps, "error">> = ({
    challenge,
    csrftoken,
    device,
    authconfig,
    oemconfig,
    isIE,
    userAgent,
}) => {
    const { t, lang } = useI18n();
    const [loginAccount, setLoginAccount] = useCookie(`${device?.client_type}.login_account`);
    const setIsSkip = (rememberLogin: string) => {
        document.cookie = `${OAuthIsSkipLabel}=${rememberLogin};max-age=${isSkipMaxAge};path=/`;
    };

    function getIsMobile(userAgent: string): boolean {
        return /mobile|nokia|iphone|ipad|android|samsung|htc|blackberry/i.test(userAgent);
    }
    const isWebMobile = userAgent ? getIsMobile(userAgent) : false;

    const store = useLocalStore<ISigninState>(() => {
        // 语言选择
        let languageUser: "CN" | "EN" | "Hant";
        if (lang === "zh-tw" || lang === "zh-hk") {
            languageUser = "Hant";
        } else if (lang.startsWith("zh")) {
            languageUser = "CN";
        } else {
            languageUser = "EN";
        }

        // 登录方式
        let authMethod = AuthMethod.Account;

        const {
            vcode_login_config: vcodeLogin,
            dualfactor_auth_server_status: dualfactor,
            sms_login_visible,
        } = authconfig!;

        if (vcodeLogin && vcodeLogin.isenable) {
            if (vcodeLogin.passwderrcnt === 0) {
                authMethod = AuthMethod.AccountAndImgCaptcha;
            } else {
                authMethod = AuthMethod.Account;
            }
        } else if (vcodeLogin && !vcodeLogin.isenable) {
            if (sms_login_visible && dualfactor && dualfactor.auth_by_sms) {
                authMethod = AuthMethod.AccountAndSmsCaptcha;
            } else if (sms_login_visible && dualfactor && dualfactor.auth_by_OTP) {
                authMethod = AuthMethod.AccountAndDynamicPassword;
            } else {
                authMethod = AuthMethod.Account;
            }
        }

        return {
            loginStatus: LoginStatus.READY,
            account: loginAccount || "",
            password: "",
            captchaInfo: {
                uuid: "",
                vcode: "",
            },
            captcha: "",
            dynamicPassword: "",
            rememberLogin: false,
            authMethod: authMethod,
            languageUser: languageUser,
            needAuthBySMS: false,
            cellphone: "",
            timeInterval: 60,
            isDuplicateSend: false,
            errorStatus: ErrorCode.Normal,
            errorInfo: null,
            isElectronOpenExternal: false,
            get getError(): string {
                switch (store.errorStatus) {
                    case ErrorCode.PasswordInvalidLocked:
                        return getErrorMessage(store.errorStatus, t, {
                            time: store.errorInfo.detail.remainlockTime,
                        });
                    default:
                        return getErrorMessage(store.errorStatus, t);
                }
            },
            checkInput(): boolean {
                switch (true) {
                    case !store.account:
                        store.errorStatus = ErrorCode.NoAccount;
                        return false;
                    case !store.password:
                        store.errorStatus = ErrorCode.NoPassword;
                        return false;
                    case !store.captcha && store.authMethod === AuthMethod.AccountAndImgCaptcha:
                        store.errorStatus = ErrorCode.NoCaptcha;
                        return false;
                    case !store.dynamicPassword && store.authMethod === AuthMethod.AccountAndDynamicPassword:
                        store.errorStatus = ErrorCode.NoDynamicPassword;
                        return false;
                    case store.password.length > 100:
                        store.errorStatus = ErrorCode.AuthFailed;
                        return false;
                    default:
                        store.loginStatus = LoginStatus.LOADING;
                        return true;
                }
            },
            async getCaptchaInfo() {
                const uuid = store.captchaInfo.uuid;
                const { data } = await openapi.post("/eacp/v1/auth1/getvcode", { uuid });
                store.captchaInfo = data;
                store.captcha = "";
            },
            async refreshAuthMethod() {
                try {
                    const {
                        data: { vcode_login_config: vcodeLogin, dualfactor_auth_server_status: dualfactor },
                    } = await openapi.post("/eacp/v1/auth1/getconfig", void 0);
                    const { sms_login_visible } = authconfig!;
                    if (vcodeLogin && vcodeLogin.isenable) {
                        if (vcodeLogin.passwderrcnt === 0) {
                            store.authMethod !== AuthMethod.AccountAndImgCaptcha
                                ? (store.authMethod = AuthMethod.AccountAndImgCaptcha)
                                : null;
                        } else {
                            store.authMethod !== AuthMethod.Account
                                ? ((store.dynamicPassword = ""),
                                  (store.captcha = ""),
                                  (store.captchaInfo = {
                                      uuid: "",
                                      vcode: "",
                                  }),
                                  (store.needAuthBySMS = false),
                                  (store.authMethod = AuthMethod.Account))
                                : null;
                        }
                    } else if (vcodeLogin && !vcodeLogin.isenable) {
                        if (sms_login_visible && dualfactor && dualfactor.auth_by_sms) {
                            store.authMethod !== AuthMethod.AccountAndSmsCaptcha
                                ? ((store.dynamicPassword = ""),
                                  (store.captcha = ""),
                                  (store.captchaInfo = {
                                      uuid: "",
                                      vcode: "",
                                  }),
                                  (store.needAuthBySMS = false),
                                  (store.authMethod = AuthMethod.AccountAndSmsCaptcha))
                                : null;
                        } else if (sms_login_visible && dualfactor && dualfactor.auth_by_OTP) {
                            store.authMethod !== AuthMethod.AccountAndDynamicPassword
                                ? ((store.captcha = ""),
                                  (store.captchaInfo = {
                                      uuid: "",
                                      vcode: "",
                                  }),
                                  (store.needAuthBySMS = false),
                                  (store.authMethod = AuthMethod.AccountAndDynamicPassword))
                                : null;
                        } else {
                            store.authMethod !== AuthMethod.Account
                                ? ((store.dynamicPassword = ""),
                                  (store.captcha = ""),
                                  (store.captchaInfo = {
                                      uuid: "",
                                      vcode: "",
                                  }),
                                  (store.needAuthBySMS = false),
                                  (store.authMethod = AuthMethod.Account))
                                : null;
                        }
                    }
                    store.authMethod === AuthMethod.AccountAndImgCaptcha
                        ? ((store.dynamicPassword = ""), (store.needAuthBySMS = false), await store.getCaptchaInfo())
                        : null;
                } catch (err) {
                    return Promise.reject(err);
                }
            },
            async auth() {
                if (store.authMethod === AuthMethod.AccountAndSmsCaptcha) {
                    // 账号密码 + 短信验证码
                    try {
                        const {
                            data: { authway, isduplicatesended, sendinterval },
                        } = await openapi.post("/eacp/v1/auth1/sendauthvcode", {
                            account: store.account,
                            password: btoa(PublicKey.encrypt(store.password, "RSAES-PKCS1-V1_5")),
                            oldtelnum: "",
                            device: device as Auth1SendauthvcodeReqDeviceinfo,
                        });
                        store.isDuplicateSend = isduplicatesended;
                        store.timeInterval = sendinterval;
                        store.cellphone = authway;
                        store.needAuthBySMS = true;
                    } catch (e) {
                        if (e.response) {
                            const {
                                response: { data: err },
                            } = e;
                            if (err.detail && err.detail.isShowStatus) {
                                // 错误密码达指定次数，开启图形验证码登录方式
                                store.dynamicPassword = "";
                                store.needAuthBySMS = false;
                                store.authMethod = AuthMethod.AccountAndImgCaptcha;
                                await store.getCaptchaInfo();
                            } else {
                                // 获取最新登录方式
                                await store.refreshAuthMethod();
                            }
                            store.errorInfo = err;
                            store.errorStatus = err.code;
                            store.loginStatus = LoginStatus.READY;
                        } else {
                            store.errorInfo = null;
                            store.errorStatus = ErrorCode.NoNetwork;
                            store.loginStatus = LoginStatus.READY;
                        }
                    }
                } else {
                    // login服务中调用getNew接口（重定向时，返回json信息，前端重定向）
                    try {
                        setLoginAccount(store.account);
                        const {
                            data: { redirect },
                        } = await axios.post(
                            `${location.protocol}//${location.hostname}:${location.port}/oauth2/signin`,
                            {
                                _csrf: csrftoken,
                                challenge,
                                account: store.account,
                                password: btoa(PublicKey.encrypt(store.password, "RSAES-PKCS1-V1_5")),
                                vcode: { id: store.captchaInfo.uuid, content: store.captcha },
                                dualfactorauthinfo: {
                                    validcode: { vcode: "" }, // 短信验证码
                                    OTP: { OTP: store.dynamicPassword }, // 动态密保
                                },
                                remember: store.rememberLogin,
                                device,
                            }
                        );
                        setIsSkip(store.rememberLogin.toString());
                        window.location.replace(redirect);
                    } catch (e) {
                        if (e.response) {
                            const {
                                response: { data: err },
                            } = e;
                            store.errorInfo = err;
                            store.errorStatus = err.code || err.status_code;
                            store.loginStatus = LoginStatus.READY;
                            if (
                                store.authMethod === AuthMethod.AccountAndImgCaptcha &&
                                err.detail &&
                                err.detail.isShowStatus
                            ) {
                                // 图形验证码登录方式，刷新图形验证码
                                await store.getCaptchaInfo();
                            } else if (
                                store.authMethod !== AuthMethod.AccountAndImgCaptcha &&
                                err.detail &&
                                err.detail.isShowStatus
                            ) {
                                // 错误密码达指定次数，开启图形验证码登录方式
                                store.dynamicPassword = "";
                                store.needAuthBySMS = false;
                                store.authMethod = AuthMethod.AccountAndImgCaptcha;
                                await store.getCaptchaInfo();
                            } else {
                                // 获取最新登录方式
                                await store.refreshAuthMethod();
                            }
                        } else {
                            store.errorInfo = null;
                            store.errorStatus = ErrorCode.NoNetwork;
                            store.loginStatus = LoginStatus.READY;
                        }
                    }
                }
            },
        };
    });

    const openThirdAuth = (authconfig?: { [key: string]: any }) => {
        document.cookie = `is_previous_login_3rd_party=true;path=/${location.protocol === "https:" ? ";secure" : ""}`;
        if (!top) return;
        if (store.isElectronOpenExternal) {
            window.parent.postMessage(
                { msg: "OauthUIOpenExternal", data: authconfig!.thirdauth.config.authServer },
                "*"
            );
        } else {
            top.window.location.href = authconfig!.thirdauth.config.authServer;
        }
        document.cookie = `login_challenge=${challenge};path=/${location.protocol === "https:" ? ";secure" : ""}`;
    };
    useEffect(() => {
        window.addEventListener("message", (event: any) => {
            const {
                data: { msg },
            } = event;
            if (msg?.startsWith("Electron")) {
                switch (msg) {
                    case "ElectronOpenExternal":
                        store.isElectronOpenExternal = true;
                        break;
                    default:
                        break;
                }
            }
        });
    }, []);

    useEffect(() => {
        if (store.authMethod === AuthMethod.AccountAndImgCaptcha) {
            store.getCaptchaInfo();
        }
    }, []);

    const autoOpenThirdAuth = () => {
        const duration = 1000;
        setTimeout(() => {
            if (
                device?.client_type !== "console_web" &&
                device?.client_type !== "deploy_web" &&
                authconfig!.thirdauth &&
                authconfig!.thirdauth.config &&
                (authconfig!.sso === "true" || authconfig!.thirdauth.config.autoCasRedirect)
            ) {
                openThirdAuth(authconfig);
            }
        }, duration);
    };

    const getMarginTop = () => {
        return oemconfig?.showPortalBanner
            ? "8px"
            : oemconfig?.showUserAgreement || oemconfig?.showPrivacyPolicy
            ? 0
            : "12px";
    };

    useEffect(() => {
        autoOpenThirdAuth();
    }, []);

    return useObserver(() => {
        return (
            <div
                className="top-signin"
                style={{
                    marginTop: getMarginTop(),
                }}
            >
                <div className={classNames("oauth2-ui-wrapper", isIE ? "oauth2-ui-wrapper-ie" : null)}>
                    <AppHead oemconfig={oemconfig!} />
                    {!store.needAuthBySMS ? (
                        <div className="signin-wrapper">
                            <div className="logo-wrapper">
                                <img
                                    className="logo-image"
                                    src={`data:image/png;base64,${oemconfig!.logo}`}
                                    onDragStart={(e) => {
                                        e.preventDefault();
                                    }}
                                />
                            </div>
                            {oemconfig?.showPortalBanner && oemconfig?.portalBanner ? (
                                <div className="title-wrapper">
                                    {t(`title-${device?.client_type}`) || oemconfig?.portalBanner}
                                </div>
                            ) : oemconfig?.showPortalBanner ? (
                                <div className="title-wrapper">
                                    {t(`title-${device?.client_type}`) || t(`title-default`)}
                                </div>
                            ) : null}

                            {authconfig!.third_auth_only ? (
                                <div className="third-auth-only">
                                    <div className="third-auth-only-avatar">
                                        <AvatarColored style={{ fontSize: "100px" }} />
                                    </div>
                                    <Button
                                        className="third-auth-only-button"
                                        type="primary"
                                        onClick={() => {
                                            document.cookie = `is_previous_login_3rd_party=true;path=/${
                                                location.protocol === "https:" ? ";secure" : ""
                                            }`;
                                            top.window.location.href = authconfig!.thirdauth.config.authServer;
                                            document.cookie = `login_challenge=${challenge};path=/${
                                                location.protocol === "https:" ? ";secure" : ""
                                            }`;
                                        }}
                                    >
                                        {t("third")}
                                    </Button>
                                </div>
                            ) : (
                                <div className="signin-content">
                                    <Form>
                                        <Form.Item>
                                            <Input
                                                name="account"
                                                className="input-item signin-item"
                                                type="text"
                                                autoComplete="off"
                                                prefix={<AccountColored className="icon" />}
                                                placeholder={t("account")}
                                                value={store.account}
                                                onChange={(e) => {
                                                    store.account = e.target.value;
                                                    store.errorStatus = ErrorCode.Normal;
                                                }}
                                                onKeyDown={(e) => {
                                                    if (
                                                        store.loginStatus === LoginStatus.READY &&
                                                        e.keyCode === 13 &&
                                                        store.checkInput()
                                                    ) {
                                                        store.auth();
                                                    }
                                                }}
                                                onDrop={(e) => {
                                                    e.preventDefault();
                                                }}
                                            />
                                        </Form.Item>
                                        <Form.Item>
                                            <Password
                                                name="password"
                                                className="input-item signin-item"
                                                type="password"
                                                autoComplete="new-password"
                                                prefix={<PasswordColored className="icon" />}
                                                placeholder={t("password")}
                                                value={store.password}
                                                onChange={(e) => {
                                                    store.password = e.target.value;
                                                    store.errorStatus = ErrorCode.Normal;
                                                }}
                                                onKeyDown={(e) => {
                                                    if (
                                                        store.loginStatus === LoginStatus.READY &&
                                                        e.keyCode === 13 &&
                                                        store.checkInput()
                                                    ) {
                                                        store.auth();
                                                    }
                                                }}
                                                onDrop={(e) => {
                                                    e.preventDefault();
                                                }}
                                            />
                                        </Form.Item>
                                        {store.authMethod === AuthMethod.AccountAndImgCaptcha ? (
                                            <Form.Item>
                                                <Input
                                                    name="captcha"
                                                    className="input-item captcha-item"
                                                    type="text"
                                                    autoComplete="off"
                                                    placeholder={t("captcha")}
                                                    value={store.captcha}
                                                    onChange={(e) => {
                                                        store.captcha = e.target.value;
                                                        store.errorStatus = ErrorCode.Normal;
                                                    }}
                                                    onKeyDown={(e) => {
                                                        if (
                                                            store.loginStatus === LoginStatus.READY &&
                                                            e.keyCode === 13 &&
                                                            store.checkInput()
                                                        ) {
                                                            store.auth();
                                                        }
                                                    }}
                                                    onDrop={(e) => {
                                                        e.preventDefault();
                                                    }}
                                                />
                                                <img
                                                    className="captcha-item-image"
                                                    src={`data:image/jpeg;base64,${store.captchaInfo.vcode}`}
                                                    onClick={() => {
                                                        store.getCaptchaInfo();
                                                    }}
                                                />
                                            </Form.Item>
                                        ) : null}
                                        {store.authMethod === AuthMethod.AccountAndDynamicPassword ? (
                                            <Form.Item>
                                                <Password
                                                    name="dynamicPassword"
                                                    className="input-item signin-item"
                                                    type="password"
                                                    autoComplete="new-password"
                                                    prefix={<DynamicPasswordColored className="icon" />}
                                                    placeholder={t("dynamic-password")}
                                                    value={store.dynamicPassword}
                                                    onChange={(e) => {
                                                        store.dynamicPassword = e.target.value;
                                                        store.errorStatus = ErrorCode.Normal;
                                                    }}
                                                    onKeyDown={(e) => {
                                                        if (
                                                            store.loginStatus === LoginStatus.READY &&
                                                            e.keyCode === 13 &&
                                                            store.checkInput()
                                                        ) {
                                                            store.auth();
                                                        }
                                                    }}
                                                    onDrop={(e) => {
                                                        e.preventDefault();
                                                    }}
                                                />
                                            </Form.Item>
                                        ) : null}
                                        {(authconfig!.rememberpass ||
                                            authconfig!.vcode_server_status.send_vcode_by_sms ||
                                            authconfig!.vcode_server_status.send_vcode_by_email) &&
                                        !authconfig!.enable_secret_mode ? (
                                            <Form.Item>
                                                {authconfig!.remember_password_visible && authconfig!.rememberpass ? (
                                                    <div className="remember-password">
                                                        <Checkbox
                                                            name="remember"
                                                            className="remember-password-text"
                                                            onChange={(e) => {
                                                                store.rememberLogin = e.target.checked;
                                                            }}
                                                            checked={store.rememberLogin}
                                                        >
                                                            {t("remember")}
                                                        </Checkbox>
                                                    </div>
                                                ) : null}
                                                {authconfig!.reset_password_visible &&
                                                (authconfig!.vcode_server_status.send_vcode_by_sms ||
                                                    authconfig!.vcode_server_status.send_vcode_by_email) &&
                                                !authconfig!.enable_secret_mode ? (
                                                    <div className="forget-password">
                                                        <a
                                                            onClick={async () => {
                                                                const {
                                                                    data: { vcode_server_status, enable_secret_mode },
                                                                } = await openapi.post(
                                                                    "/eacp/v1/auth1/getconfig",
                                                                    void 0
                                                                );
                                                                if (
                                                                    ((vcode_server_status as any).send_vcode_by_sms ||
                                                                        (vcode_server_status as any)
                                                                            .send_vcode_by_email) &&
                                                                    !enable_secret_mode
                                                                ) {
                                                                    window.location.href = `/oauth2/password/reset?login_challenge=${challenge}&redirect=${location.protocol}//${location.hostname}:${location.port}/oauth2/signin?login_challenge=${challenge}`;
                                                                } else {
                                                                    store.errorStatus =
                                                                        ErrorCode.CloseForgetPasswordResetBySend;
                                                                }
                                                            }}
                                                        >
                                                            {t("reset")}
                                                        </a>
                                                    </div>
                                                ) : null}
                                            </Form.Item>
                                        ) : null}
                                        <Form.Item>
                                            <Button
                                                className={classNames(
                                                    "oem-button",
                                                    "as-components-oem-background-color",
                                                    !(
                                                        (authconfig!.rememberpass ||
                                                            authconfig!.vcode_server_status.send_vcode_by_sms ||
                                                            authconfig!.vcode_server_status.send_vcode_by_email) &&
                                                        !authconfig!.enable_secret_mode
                                                    ) && "signin-button"
                                                )}
                                                type="primary"
                                                onClick={() => {
                                                    if (store.loginStatus === LoginStatus.READY && store.checkInput()) {
                                                        store.auth();
                                                    }
                                                }}
                                            >
                                                {store.loginStatus === LoginStatus.READY
                                                    ? t("log-in")
                                                    : t("logging-in")}
                                            </Button>
                                        </Form.Item>
                                    </Form>
                                    {store.errorStatus === ErrorCode.Normal ? null : (
                                        <div className="error-message-text">{store.getError}</div>
                                    )}
                                    {store.errorStatus === ErrorCode.PasswordFailure ||
                                    store.errorStatus === ErrorCode.PasswordInsecure ||
                                    store.errorStatus === ErrorCode.PasswordIsInitial ? (
                                        <div className="change-password-text">
                                            <a
                                                href={`/oauth2/password/change?login_challenge=${challenge}&redirect=${
                                                    location.protocol
                                                }//${location.hostname}:${
                                                    location.port
                                                }/oauth2/signin?login_challenge=${challenge}&account=${encodeURIComponent(
                                                    store.account
                                                )}`}
                                            >
                                                {t("change")}
                                            </a>
                                        </div>
                                    ) : null}
                                    {authconfig!.third_party_login_visible &&
                                    authconfig!.thirdauth &&
                                    authconfig!.thirdauth.config &&
                                    !authconfig!.thirdauth.config.hideThirdLogin ? (
                                        <div className="third-signin">
                                            {device?.client_type === "web" ? (
                                                <a
                                                    onClick={() => {
                                                        document.cookie = `is_previous_login_3rd_party=true;path=/${
                                                            location.protocol === "https:" ? ";secure" : ""
                                                        }`;
                                                        top.window.location.href = authconfig!.thirdauth.config.authServer;
                                                        document.cookie = `login_challenge=${challenge};path=/${
                                                            location.protocol === "https:" ? ";secure" : ""
                                                        }`;
                                                    }}
                                                >
                                                    {(authconfig!.thirdauth &&
                                                        authconfig!.thirdauth.config &&
                                                        authconfig!.thirdauth.config.loginButtonText) ||
                                                    authconfig!.third_auth_only
                                                        ? authconfig!.thirdauth.config.loginButtonText
                                                        : t("third")}
                                                </a>
                                            ) : device?.client_type === "console_web" ? (
                                                <a
                                                    onClick={() => {
                                                        top.window.location.href = authconfig!.thirdauth.config.authServer;
                                                        document.cookie = `login_challenge=${challenge};path=/${
                                                            location.protocol === "https:" ? ";secure" : ""
                                                        }`;
                                                    }}
                                                >
                                                    {authconfig!.thirdauth &&
                                                    authconfig!.thirdauth.config &&
                                                    authconfig!.thirdauth.config.loginButtonText
                                                        ? authconfig!.thirdauth.config.loginButtonText
                                                        : t("third")}
                                                </a>
                                            ) : (
                                                <a
                                                    onClick={() => {
                                                        openThirdAuth(authconfig);
                                                    }}
                                                >
                                                    {authconfig!.thirdauth &&
                                                    authconfig!.thirdauth.config &&
                                                    authconfig!.thirdauth.config.loginButtonText
                                                        ? authconfig!.thirdauth.config.loginButtonText
                                                        : t("third")}
                                                </a>
                                            )}
                                        </div>
                                    ) : null}
                                </div>
                            )}
                            {device?.client_type === "ios" || device?.client_type === "android" || isWebMobile ? (
                                oemconfig?.showUserAgreement || oemconfig?.showPrivacyPolicy ? (
                                    <div
                                        className="login-view-all"
                                        style={{
                                            top: oemconfig?.showPortalBanner
                                                ? store.languageUser === "EN"
                                                    ? "414px"
                                                    : "392px"
                                                : "404px",
                                        }}
                                    >
                                        {t("login-agree")}
                                        {oemconfig?.showUserAgreement ? (
                                            <a
                                                onClick={() => {
                                                    window.open(
                                                        `${location.protocol}//${location.hostname}:${location.port}/Agreement/UserAgreement/ServiceAgreement-${store.languageUser}.html`
                                                    );
                                                }}
                                                style={{ marginLeft: store.languageUser === "EN" ? "5px" : 0 }}
                                            >
                                                {t("user-agreement")}
                                            </a>
                                        ) : null}

                                        {oemconfig?.showUserAgreement && oemconfig?.showPrivacyPolicy ? (
                                            <span>{t("login-symbol")}</span>
                                        ) : null}

                                        {oemconfig?.showPrivacyPolicy ? (
                                            <span>
                                                <a
                                                    onClick={() => {
                                                        window.open(
                                                            `${location.protocol}//${location.hostname}:${location.port}/Agreement/Privacy/Privacy-${store.languageUser}.html`
                                                        );
                                                    }}
                                                    style={{ marginLeft: store.languageUser === "EN" ? "5px" : 0 }}
                                                >
                                                    {t("privacy-policy")}
                                                </a>
                                            </span>
                                        ) : null}
                                    </div>
                                ) : null
                            ) : null}
                        </div>
                    ) : null}
                    {store.needAuthBySMS ? (
                        <AuthBySMS
                            account={store.account}
                            password={store.password}
                            cellphone={store.cellphone}
                            timeInterval={store.timeInterval}
                            isDuplicateSend={store.isDuplicateSend}
                            device={device!}
                            challenge={challenge!}
                            rememberLogin={store.rememberLogin}
                            t={t}
                            csrftoken={csrftoken}
                            refreshAuthMethod={store.refreshAuthMethod}
                        />
                    ) : null}
                </div>
            </div>
        );
    });
};

export default withI18n<ISigninProps>(({ error, ...otherProps }) => {
    const { lang } = useI18n();
    if (error) {
        return <ErrorPage {...error} lang={lang} />;
    }

    return <SignInForm {...otherProps} />;
});

export const getServerSideProps: GetI18nServerSideProps<ISigninProps> = async ({ req, res, query }) => {
    const userAgent = req ? req.headers["user-agent"] : undefined;
    const csrftoken = (req as Request).csrfToken();
    const { login_challenge: queryChallenge = "", ...params } = query;
    const { login_challenge: cookieChallenge = "" } = (req as Request).cookies;
    const challenge = (queryChallenge || cookieChallenge || "") as string;
    const requestLanguage = getRequestLanguage(req);
    const isIE = (req.headers["user-agent"] && /rv:11.0/.test(req.headers["user-agent"])) || false;
    delete params["lang"];

    if (challenge) {
        try {
            const { skip, subject, request_url, client, session_id } = await getLoginRequest(challenge);
            const loginRequstQuery = querystring.parse(request_url);
            const { udids, sso } = loginRequstQuery;
            const metadata = (client.metadata && client.metadata.device) || {
                name: "",
                description: "",
                client_type: "unknown",
            };
            const { name = "", description = "", client_type = "" } = metadata;
            const {
                third_party_login_visible = true,
                remember_password_visible = true,
                reset_password_visible = true,
                sms_login_visible = true,
            } = (client.metadata && client.metadata.login_form) || {};
            let { lang } = loginRequstQuery;

            if (!lang || !supportLanguages.includes(lang as string)) {
                lang = requestLanguage;
            }

            (res as Response).cookie("lang", lang, {
                httpOnly: false,
                secure: true,
            });

            const device = {
                name: name,
                description: description,
                client_type: client_type,
                udids: typeof udids === "string" ? [udids] : [...(udids || [])],
            } as Auth1SendauthvcodeReqDeviceinfo;

            if (skip) {
                const lastTimestamp = Date.now();
                console.log(`[${Date()}] [INFO]  {/api/authentication/v1/session/${session_id}} GET}  START`);
                const {
                    data: { context },
                } = await authenticationPrivateApi.get(`/api/authentication/v1/session/${session_id}`);
                console.log(
                    `[${Date()}] [INFO]  {/api/authentication/v1/session/${session_id}} GET}  SUCCESS +${
                        Date.now() - lastTimestamp
                    }ms`
                );
                const { redirect_to } = await acceptLoginRequest(challenge, {
                    subject,
                    context,
                });
                (res as Response).redirect(redirect_to);
                return {
                    props: {
                        lang: lang as string,
                        csrftoken,
                    },
                };
            } else if (queryChallenge) {
                let lastTimestamp = Date.now();
                console.log(`[${Date()}] [INFO]  {/api/eacp/v1/config/getoemconfigbysection} POST}  START`);
                // 获取通用配置
                const {
                    data: { theme, showPortalBanner, showUserAgreement, showPrivacyPolicy },
                } = await eacpPublicApi.post("/api/eacp/v1/config/getoemconfigbysection", { section: "anyshare" });
                const showBanner = Boolean(showPortalBanner === "true");
                const showAgreement = Boolean(showUserAgreement === "true");
                const showPolicy = Boolean(showPrivacyPolicy === "true");
                let section: string;

                switch (lang) {
                    case "zh":
                    case "zh-cn":
                        section = "shareweb_zh-cn";
                        break;
                    case "zh-tw":
                    case "zh-hk":
                        section = "shareweb_zh-tw";
                        break;
                    default:
                        section = "shareweb_en-us";
                        break;
                }
                // 获取oem配置
                const {
                    data: { [`logo.png`]: logo, product, [`favicon.ico`]: favicon, portalBanner },
                } = await eacpPublicApi.post("/api/eacp/v1/config/getoemconfigbysection", { section });
                console.log(
                    `[${Date()}] [INFO]  {/api/eacp/v1/config/getoemconfigbysection} POST}  SUCCESS +${
                        Date.now() - lastTimestamp
                    }ms`
                );
                lastTimestamp = Date.now();
                console.log(`[${Date()}] [INFO]  {/api/eacp/v1/auth1/getconfig} POST}  START`);
                // 获取认证配置
                const {
                    data: {
                        enable_secret_mode,
                        vcode_server_status,
                        oemconfig: { rememberpass },
                        vcode_login_config,
                        dualfactor_auth_server_status,
                        thirdauth,
                    },
                } = await eacpPublicApi.post("/api/eacp/v1/auth1/getconfig", void 0);
                console.log(
                    `[${Date()}] [INFO]  {/api/eacp/v1/auth1/getconfig} POST}  SUCCESS +${Date.now() - lastTimestamp}ms`
                );

                return {
                    props: {
                        lang: lang as string,
                        challenge: challenge,
                        csrftoken,
                        device,
                        authconfig: {
                            enable_secret_mode,
                            rememberpass,
                            vcode_server_status,
                            vcode_login_config,
                            dualfactor_auth_server_status,
                            thirdauth: thirdauth ? thirdauth : null,
                            third_auth_only:
                                thirdauth &&
                                thirdauth.config &&
                                thirdauth.config.hideLogin &&
                                !thirdauth.config.hideThirdLogin &&
                                device.client_type === "web"
                                    ? true
                                    : false,
                            third_party_login_visible,
                            remember_password_visible,
                            reset_password_visible,
                            sms_login_visible,
                            sso: sso || "",
                        },
                        oemconfig: {
                            theme,
                            logo,
                            product,
                            favicon,
                            showPortalBanner: showBanner,
                            portalBanner,
                            showUserAgreement: showAgreement,
                            showPrivacyPolicy: showPolicy,
                        },
                        isIE,
                        userAgent,
                    },
                };
            } else if (Object.keys(params).filter((key) => params[key]).length) {
                let lastTimestamp = Date.now();
                console.log(`[${Date()}] [INFO]  {/api/eacp/v1/auth1/getconfig} POST}  START`);
                // 获取第三方认证id
                const {
                    data: { thirdauth },
                } = await eacpPublicApi.post("/api/eacp/v1/auth1/getconfig", void 0);
                console.log(
                    `[${Date()}] [INFO]  {/api/eacp/v1/auth1/getconfig} POST}  SUCCESS +${Date.now() - lastTimestamp}ms`
                );

                let user_id: string, context: any;

                if (device!.client_type === "console_web" || device!.client_type === "deploy_web") {
                    lastTimestamp = Date.now();
                    console.log(`[${Date()}] [INFO]  {/api/eacp/v1/auth1/consolelogin} POST}  START`);
                    // 管理控制台第三方登录
                    ({
                        data: { user_id, context },
                    } = await eacpPrivateApi.post("/api/eacp/v1/auth1/consolelogin", {
                        credential: {
                            type: "third_party",
                            params,
                        },
                        device,
                        ip: (req as Request).ip || "",
                    }));
                    console.log(
                        `[${Date()}] [INFO]  {/api/eacp/v1/auth1/consolelogin} POST}  SUCCESS +${
                            Date.now() - lastTimestamp
                        }ms`
                    );
                } else {
                    lastTimestamp = Date.now();
                    console.log(`[${Date()}] [INFO]  {/api/eacp/v1/auth1/getbythirdparty} POST}  START`);
                    // 客户端第三方认证
                    ({
                        data: { user_id, context },
                    } = await eacpPrivateApi.post("/api/eacp/v1/auth1/getbythirdparty", {
                        thirdpartyid: thirdauth.id,
                        params,
                        device,
                        ip: (req as Request).ip || "",
                    }));
                    console.log(
                        `[${Date()}] [INFO]  {/api/eacp/v1/auth1/getbythirdparty} POST}  SUCCESS +${
                            Date.now() - lastTimestamp
                        }ms`
                    );
                }

                (res as Response).clearCookie("login_challenge");

                const { redirect_to } = await acceptLoginRequest(challenge, {
                    subject: user_id,
                    context,
                    remember: true,
                });

                console.log(`[${Date()}] [INFO]  {/api/authentication/v1/session/${session_id} PUT} START`);
                await authenticationPrivateApi.put(`/api/authentication/v1/session/${session_id}`, {
                    subject: user_id,
                    client_id: client.client_id,
                    remember_for: 30 * 24 * 60 * 60,
                    context,
                });
                console.log(
                    `[${Date()}] [INFO]  {/api/authentication/v1/session/${session_id} PUT} SUCCESS  +${
                        Date.now() - lastTimestamp
                    }ms`
                );

                (res as Response).redirect(redirect_to);

                return {
                    props: {
                        lang: lang as string,
                        csrftoken,
                    },
                };
            } else {
                console.error(`参数不合法，可能第三方登录时缺少票据`);
                res.statusCode = 400;
                return {
                    props: {
                        lang: lang as string,
                        csrftoken,
                        error: {
                            code: 400000000,
                            cause: "参数不合法",
                            message: "第三方登录时缺少票据",
                        },
                    },
                };
            }
        } catch (e) {
            const path = e && e.request && (e.request.path || (e.request._options && e.request._options.path));
            console.error(`[${Date()}] [ERROR]  ${path}  ERROR ${JSON.stringify(e && e.response && e.response.data)}`);
            if (e && e.response && e.response.status !== 503) {
                const { status, data } = e.response;
                res.statusCode = status;
                return {
                    props: {
                        lang: requestLanguage,
                        csrftoken,
                        error: data,
                    },
                };
            } else {
                const service = getServiceNameFromApi(path);
                console.error(`内部错误，连接${service}服务失败`);
                res.statusCode = 500;
                return {
                    props: {
                        lang: requestLanguage,
                        csrftoken,
                        error: {
                            code: getErrorCodeFromService(service),
                            cause: "内部错误",
                            message: `连接${service}服务失败`,
                        },
                    },
                };
            }
        }
    } else {
        console.error(`参数不合法，缺少login_challenge参数`);
        res.statusCode = 400;
        return {
            props: {
                lang: requestLanguage,
                csrftoken,
                error: {
                    code: 400000000,
                    cause: "参数不合法",
                    message: "缺少login_challenge参数",
                },
            },
        };
    }
};
